<?php

class MsggItemHandler
{
    use util_person;
    use util_array;

    public function handler(CEvent $event)
    {

        $params = $event->params;
        $eventType = isset($params['eventType']) ? $params['eventType'] : '';
        switch ($eventType) {
            case MsggItem::EVENT_TYPE_ON_AFTER_EXECUTE:
                $this->handlerAfterExecute($event);
                break;
            case MsggItem::EVENT_TYPE_ON_AFTER_HOOK:
                $this->handlerAfterHook($event);
                break;

        }
    }

    public function handlerAfterHook(CEvent $event)
    {
        try {
            $params = $event->params;
            $sender = $event->sender;
            $eventType = isset($params['eventType']) ? $params['eventType'] : '';
            if (!empty($eventType) && $eventType == MsggItem::EVENT_TYPE_ON_AFTER_HOOK && $sender && $sender instanceof MsggItem) {
                $type = $sender->type;
                //when item is call type and success, merge the other calls in the flowing one minute  with a mail
                switch ($type) {
                    case MsggItem::TYPE_CALL:
                        $this->forCallBack($sender, $params);
                        $this->handlerCall($sender, $params);
                        break;
                }
            } else {
                Yii::log('eventType or sender is null or sender is not msggitem', CLogger::LEVEL_ERROR, 'MsggItemHandler.handlerAfterHook');
            }

        } catch (Exception $e) {
            Yii::log('error' . $e->getMessage(), CLogger::LEVEL_ERROR, 'MsggItemHandler.handlerAfterHook');
        }


    }

    public function handlerAfterExecute(CEvent $event)
    {
        try {
            $params = $event->params;
            $sender = $event->sender;
            $eventType = isset($params['eventType']) ? $params['eventType'] : '';
            if (!empty($eventType) && $eventType == MsggItem::EVENT_TYPE_ON_AFTER_EXECUTE && $sender && $sender instanceof MsggItem) {
                $type = $sender->type;
                //when item is call type and success, merge the other calls in the flowing one minute  with a mail
                switch ($type) {
                    case MsggItem::TYPE_CALL:
                        $this->handlerCall($sender, $params);
                        break;
                }
            } else {
                Yii::log('eventType or sender is null or sender is not msggitem', CLogger::LEVEL_ERROR, 'MsggItemHandler.handlerAfterExecute');
            }

        } catch (Exception $e) {
            Yii::log('error' . $e->getMessage(), CLogger::LEVEL_ERROR, 'MsggItemHandler.handlerAfterExecute');
        }


    }

    public function handlerBeforeExecute(CEvent $event)
    {
        try {
            $params = $event->params;
            $sender = $event->sender;
            $eventType = isset($params['eventType']) ? $params['eventType'] : '';
            if (!empty($eventType) && $eventType == MsggItem::EVENT_TYPE_ON_BEFORE_EXECUTE && $sender && $sender instanceof MsggItem) {
                $type = $sender->type;
                //when item is call type and success, merge the other calls in the flowing one minute  with a mail
                switch ($type) {
                    case MsggItem::TYPE_CALL:
                        $this->forNotice($sender, $params);
                        break;
                }
            } else {
                Yii::log('eventType or sender is null or sender is not msggitem', CLogger::LEVEL_ERROR, 'MsggItemHandler.handlerBeforeExecute');
            }

        } catch (Exception $e) {
            Yii::log('error' . $e->getMessage(), CLogger::LEVEL_ERROR, 'MsggItemHandler.handlerBeforeExecute');
        }

    }

    private function forCallBack($sender, $params)
    {
        switch ($sender->type) {
            case MsggItem::TYPE_CALL:
                $callbackparams = json_decode($sender->call_back_params, true);
                if (empty($callbackparams)) {
                    break;
                }
                $params = array();
                $params['user_params'] = self::util_array_get($callbackparams, 'params', array());
                $attrs = array();
                $attrs['url'] = self::util_array_get($callbackparams, 'url', null);
                $attrs['iid'] = $sender->id;
                $attrs['retry'] = self::util_array_get($callbackparams, 'retry', 0);
                $attrs['alive'] = self::util_array_get($callbackparams, 'alive', 0);
                if ($sender->isSuccess()) {
                    $params['id'] = $sender->id;
                    $params['status'] = 'success';
                    $params['time'] = time();
                    $result = MsggItemCallback::callBack($params, MsggItem::TYPE_CALL, $attrs);
                } elseif ($sender->isComplete()) {
                    $params['id'] = $sender->id;
                    $params['status'] = 'failed';
                    $params['time'] = time();
                    $result = MsggItemCallback::callBack($params, MsggItem::TYPE_CALL, $attrs);
                } elseif ($sender->isError() || $sender->isFailure()) {
                    $params['id'] = $sender->id;
                    $params['status'] = 'complete';
                    $params['time'] = time();
                    $result = MsggItemCallback::callBack($params, MsggItem::TYPE_CALL, $attrs);
                }
                if (isset($result['code']) && $result['code'] == 0) {
                    Yii::log('callBack success ', CLogger::LEVEL_ERROR, 'MsggItemHandler.handlerAfterHook');
                } else {
                    Yii::log('callBack failed ', CLogger::LEVEL_ERROR, 'MsggItemHandler.handlerAfterHook');
                }
                break;
            default:
                break;
        }
    }

    private function handlerCall($sender, $params)
    {
        if ($sender instanceof MsggItem) {
            $mergeCallSize = self::util_array_get($params, 'mergeCallSize', null);
            $pid = $sender->pid;
            if ($sender->isSuccess() && $pid) {
                //bundle the call wait to send
                $bundler = new MsggBundler(MsggItem::TYPE_CALL, [MsggItem::STATUS_WAITING, MsggItem::STATUS_RETRYING], $mergeCallSize,$pid,null,time()+86400);
                $titleGen = function ($pid, $ids,$bundler) {
                    return 'msgg 提醒您，为了信息质量自动帮您合并了部分电话信息！';
                };
                $paramsGen = function ($pid, $ids,$bundler) {
                    $params = array();
                    if ($bundler instanceof MsggBundler) {
                        $params[]=['label'=>'合并信息类型','value'=>$bundler->getType()];
                    }
                    $params[] = ['label' => '合并信息数量', 'value' => sizeof($ids)];
                    return $params;
                };
                $bundler->setGenerator($titleGen,$paramsGen);
                try {
                    $bundler->bundle();
                } catch (Exception $e) {
                    Yii::log($e->getMessage(), $e->getCode(),  __METHOD__);
                }
            } elseif ($sender->isFailure()&&$pid) {
                //bundle fail call to notice the person
                $bundler = new MsggBundler(MsggItem::TYPE_CALL, [MsggItem::STATUS_ERROR, MsggItem::STATUS_FAILURE], 0);
                $titleGen = function ($pid, $ids,$bundler) {
                    return 'msgg 提醒您有部分电话未成功拨打！';
                };
                $paramsGen = function ($pid,$ids,$bundler) {
                    $params = array();
                    $params[]=['label'=>'提示','value'=>'msgg提醒你有部分电话未能成功接听！'];
                    $params[]=['label'=>'截止日期','value'=>date('Y-m-d H:m:s',$bundler->getBundleTimeEnd())];
                    $params[] = ['label' => '电话数量', 'value' => sizeof($ids)];
                    return $params;
                };
                $bundler->setGenerator($titleGen,$paramsGen);
                try {
                    $bundler->bundle();
                } catch (Exception $e) {
                    Yii::log($e->getMessage(), $e->getCode(),  __METHOD__);
                }

            }

        }

    }

    private function forNotice($sender, $params)
    {

        $pid = $sender->pid;
        $type = $sender->type;
        $size = self::util_array_get($params, 'mergeCallSize', null);
        $person = AlarmPerson::model()->findByPk($pid);
        if (empty($person) || empty($size) || $pid == 0 || $type != MsggItem::TYPE_CALL) {
            Yii::log('empty in some params', CLogger::LEVEL_ERROR, 'MsggItemHandler.forNotice');
            return;
        }
        $msgs = MsggItem::model()->findAllByAttributes(
            [
                'pid' => $pid,
                'status' => [MsggItem::STATUS_WAITING, MsggItem::STATUS_RETRYING],
                'type' => MsggItem::TYPE_CALL
            ]);
        if (count($msgs) < $size) {
            return;
        }
        $dateBegin = date('Y-m-d H:i:s', time());
        $adminMail = self::util_admin_person()->mail;
        $refer = '您接下来可能会持续受到' . count($msgs) . '个电话,可选择接听最近一个电话取消余下电话发送.请注意其他渠道的信息!!!';
        foreach ($msgs as $msg) {
            $params = $msg->getParams();
            $mediaName = isset($params['media']) ? $params['media'] : 'default';
            switch ($mediaName) {
                case 'qqbot_new_message':
                    $info = 'qq 有人找你';
                    break;
                case 'qqbot_qrcode':
                    $info = '今晚值班';
                    break;
                case 'qqbot_login_fail':
                    $info = 'qq 机器人登陆失败';
                    break;
                default:
                case 'default':
                    $info = '您有告警!!';
                    break;
            }
            $details[$mediaName] = $info;
        }
        $detail = implode('\n', $details);
        $contentParams = array('admin_mail' => $adminMail, 'refer' => $refer, 'detail' => $detail, 'dateBegin' => $dateBegin);

        $content = $this->genContent($contentParams);
        $params = array('to' => $person->wechat, 'content' => $content);
        $attrs = ['level' => MsggItem::INNER_LEVEL, 'pid' => $pid];
        $noticeMsg = MsggItem::build(MsggItem::TYPE_WECHAT, $params, $attrs);
        if ($noticeMsg && $noticeMsg->save()) {
            $result = $noticeMsg->execute();
            if ($result['code'] != 0) {
                Yii::log('NoticeMsg execute fail' . json_encode($result), CLogger::LEVEL_ERROR, 'MsggItemHandler.forNotice');
            }
        }
    }

    private function genContent($params = [], $isHtml = false)
    {
        $begin = isset($params['dateBegin']) ? $params['dateBegin'] : '';
        $refer = isset($params['refer']) ? $params['refer'] : '';
        $detail = isset($params['detail']) ? $params['detail'] : '';
        $admin_mail = self::util_array_get($params, 'admin_mail', '');
        $url = self::util_array_get($params, 'url', null);
        $alarm_label = self::util_array_get($params, 'alarm_label', null);

        $lines = array();
        $lines[] = "【msgg】";
        $lines[] = "【时间】:" . $begin;
        $lines[] = "【描述】:" . $refer;
        $lines[] = "【电话具体内容】:" . ($isHtml ? str_replace(array("\r\n", "\n", "\r"), '<br>', $detail) : $detail);
        $lines[] = '【如有任何问题请联系管理员邮箱】:' . $admin_mail;
        if (!empty($alarm_label)) {
            $lines[] = ("【关联告警】:" . $alarm_label);
        }
        $lines[] = !empty($url) ? ($isHtml ? '<a href="' . $url . '">我要查看</a>' : ("我要查看:" . $url . "\n")) : '';
        return implode(($isHtml ? '<br>' : "\n"), $lines);
    }


}